﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cinchoo.Core.Configuration;
using System.Reflection;
using System.IO;
using Cinchoo.Core;
using System.ComponentModel;

namespace ChoWorkflowServer.Model
{
    [ChoNameValueConfigurationSection("workflowServerSettings", Silent=false)]
    public class ChoWorkflowServerSettings : ChoConfigurableObject
    {
        [ChoPropertyInfo("turnOnUDP", DefaultValue = "true")]
        public bool TurnOnUDP;

        [Category("Options")]
        [Description("UDP Server Port.")]
        [DisplayName("UDPPort")]
        [ChoPropertyInfo("port", DefaultValue = "11000")]
        public int Port
        {
            get;
            set;
        }

        [Category("Options")]
        [Description("UDP Server Address.")]
        [DisplayName("UDPAddress")]
        [ChoPropertyInfo("udpIPAddress", DefaultValue = "224.5.6.7")]
        [ChoNotNullOrEmptyValidator]
        public string UDPIPAddress
        {
            get;
            set;
        }

        [ChoPropertyInfo("controllerIPAddress", DefaultValue = "127.0.0.1")]
        //[ChoNotNullOrEmptyValidator]
        public string ControllerIPAddress;

        [ChoPropertyInfo("pollInterval", DefaultValue = "1000")]
        public int PollInterval;

        [ChoPropertyInfo("createNoWindow")]
        public bool CreateNoWindow;

        [ChoPropertyInfo("workflowDefPaths")]
        //[ChoNotNullOrEmptyValidator]
        public string WorkflowDefPaths;

        [ChoPropertyInfo("softAbortTimeout")]
        public int SoftAbortTimeout;

        [ChoPropertyInfo("operationTimeoutInSecs", DefaultValue = "30")]
        public int OperationTimeout;

        [ChoIgnoreProperty]
        //[ChoNotNullOrEmptyValidator]
        public string DataModelHostUrl;

        [ChoPropertyInfo("maxNoOfConcurrentTasks")]
        public int MaxNoOfConcurrentTasks;

        [ChoPropertyInfo("maxNoOfAllowedTasks")]
        public int MaxNoOfAllowedTasks;

        [ChoIgnoreProperty]
        public string DataModelEndPointUrl;

        [ChoIgnoreProperty]
        [Browsable(false)]
        public int UDPPort
        {
            get { return Port + 2; }
        }

        protected override void OnAfterConfigurationObjectMemberLoaded(string memberName, string propertyName, object value)
        {
            if (memberName == "PollInterval" && PollInterval < 1)
            {
                PollInterval = 5000;
            }
            else if (memberName == "ControllerIPAddress")
            {
                BuildUri();
            }
        }

        protected override void OnAfterConfigurationObjectLoaded()
        {
            if (Port < 0)
                throw new ApplicationException("Invalid [{0}] port number passed.".FormatString(Port));

            if (MaxNoOfConcurrentTasks <= 0)
                MaxNoOfConcurrentTasks = 10;

            if (MaxNoOfAllowedTasks <= 0)
#if DEBUG
                MaxNoOfAllowedTasks = 100;
#else
                MaxNoOfAllowedTasks = 100;
#endif
            if (WorkflowDefPaths.IsNullOrWhiteSpace())
                WorkflowDefPaths = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            if (SoftAbortTimeout <= 0)
                SoftAbortTimeout = 5000;
            if (OperationTimeout <= 0)
                OperationTimeout = 30;

            BuildUri();

            base.OnAfterConfigurationObjectLoaded();
        }

        protected override void OnAfterConfigurationObjectMemberSet(string memberName, string propertyName, object value)
        {
            if (memberName == "ControllerIPAddress")
            {
                BuildUri();
            }
            base.OnAfterConfigurationObjectMemberSet(memberName, propertyName, value);
        }

        private void BuildUri()
        {
            //UriBuilder uri = DataModelHostUrl.IsNullOrWhiteSpace() ? new UriBuilder() : new UriBuilder(DataModelHostUrl);
            UriBuilder uri = new UriBuilder();
            uri.Host = "localhost";
            uri.Port = Port + 1;
            DataModelEndPointUrl = uri.ToString();

            //UriBuilder uri1 = DataModelHostUrl.IsNullOrWhiteSpace() ? new UriBuilder() : new UriBuilder(DataModelHostUrl);
            DataModelHostUrl = null;

            if (!ControllerIPAddress.IsNullOrWhiteSpace())
            {
                UriBuilder uri1 = new UriBuilder();
                uri1.Host = ControllerIPAddress.IsNullOrWhiteSpace() ? "Unknown" : ControllerIPAddress;
                uri1.Port = Port + 1;
                DataModelHostUrl = uri1.ToString();
            }
        }
    }
}
